package org.erp.store.infrastructure.config;

import org.erp.common.enums.DeviceInventoryEvent;
import org.erp.store.infrastructure.enums.DeviceInventoryState;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 库存状态转换管理器
 * 
 */
@Component
public class InventoryStateTransitionManager {
    
    // 预构建状态转换表 
    private static final Map<DeviceInventoryEvent, Map<DeviceInventoryState, DeviceInventoryState>> STATE_TRANSITION_MAP;
    
    static {
        STATE_TRANSITION_MAP = new HashMap<>();
        
        // ALLOCATE事件的状态转换
        Map<DeviceInventoryState, DeviceInventoryState> allocateMap = new HashMap<>();
        allocateMap.put(DeviceInventoryState.INBOUND, DeviceInventoryState.TRANSFERRING);
        STATE_TRANSITION_MAP.put(DeviceInventoryEvent.ALLOCATE, allocateMap);
        
        // CANCEL_REJECT事件的状态转换
        Map<DeviceInventoryState, DeviceInventoryState> cancelRejectMap = new HashMap<>();
        cancelRejectMap.put(DeviceInventoryState.REJECTED, DeviceInventoryState.TRANSFERRING);
        STATE_TRANSITION_MAP.put(DeviceInventoryEvent.CANCEL_REJECT, cancelRejectMap);
        
        // HANDOVER事件的状态转换
        Map<DeviceInventoryState, DeviceInventoryState> handoverMap = new HashMap<>();
        handoverMap.put(DeviceInventoryState.TRANSFERRING, DeviceInventoryState.HANDOVER);
        STATE_TRANSITION_MAP.put(DeviceInventoryEvent.HANDOVER, handoverMap);
        
        // SELL事件的状态转换
        Map<DeviceInventoryState, DeviceInventoryState> sellMap = new HashMap<>();
        sellMap.put(DeviceInventoryState.HANDOVER, DeviceInventoryState.SOLD);
        STATE_TRANSITION_MAP.put(DeviceInventoryEvent.SELL, sellMap);
        
        // REJECT事件的状态转换
        Map<DeviceInventoryState, DeviceInventoryState> rejectMap = new HashMap<>();
        rejectMap.put(DeviceInventoryState.TRANSFERRING, DeviceInventoryState.REJECTED);
        STATE_TRANSITION_MAP.put(DeviceInventoryEvent.REJECT, rejectMap);
        
        // REJECT_TO_INBOUND事件的状态转换（驳回 -> 入库）
        Map<DeviceInventoryState, DeviceInventoryState> rejectToInboundMap = new HashMap<>();
        rejectToInboundMap.put(DeviceInventoryState.REJECTED, DeviceInventoryState.INBOUND);
        STATE_TRANSITION_MAP.put(DeviceInventoryEvent.REJECT_TO_INBOUND, rejectToInboundMap);

        // RETURN_TO_INBOUND事件的状态转换（待返库 -> 入库）
        Map<DeviceInventoryState, DeviceInventoryState> returnToInboundMap = new HashMap<>();
        returnToInboundMap.put(DeviceInventoryState.WAIT_RETURN, DeviceInventoryState.INBOUND);
        STATE_TRANSITION_MAP.put(DeviceInventoryEvent.RETURN_TO_INBOUND, returnToInboundMap);
        
        // REQUEST_RETURN事件的状态转换
        Map<DeviceInventoryState, DeviceInventoryState> requestReturnMap = new HashMap<>();
        requestReturnMap.put(DeviceInventoryState.HANDOVER, DeviceInventoryState.WAIT_RETURN);
        STATE_TRANSITION_MAP.put(DeviceInventoryEvent.REQUEST_RETURN, requestReturnMap);
        
        // REQUEST_REFUND事件的状态转换
        Map<DeviceInventoryState, DeviceInventoryState> requestRefundMap = new HashMap<>();
        requestRefundMap.put(DeviceInventoryState.HANDOVER, DeviceInventoryState.WAIT_REFUND);
        STATE_TRANSITION_MAP.put(DeviceInventoryEvent.REQUEST_REFUND, requestRefundMap);
        
        // CONFIRM_REFUND事件的状态转换
        Map<DeviceInventoryState, DeviceInventoryState> confirmRefundMap = new HashMap<>();
        confirmRefundMap.put(DeviceInventoryState.WAIT_REFUND, DeviceInventoryState.REFUNDED);
        STATE_TRANSITION_MAP.put(DeviceInventoryEvent.CONFIRM_REFUND, confirmRefundMap);
    }
    
    /**
     * 验证状态转换是否合法
     * 
     * @param originalState 原始状态
     * @param targetEvent 目标事件
     * @return 是否允许转换
     */
    public boolean isTransitionValid(DeviceInventoryState originalState, DeviceInventoryEvent targetEvent) {
        Map<DeviceInventoryState, DeviceInventoryState> eventTransitions = STATE_TRANSITION_MAP.get(targetEvent);
        return eventTransitions != null && eventTransitions.containsKey(originalState);
    }
    
    /**
     * 获取状态转换后的目标状态
     * 
     * @param originalState 原始状态
     * @param targetEvent 目标事件
     * @return 目标状态，如果不允许转换则返回null
     */
    public DeviceInventoryState getTargetState(DeviceInventoryState originalState, DeviceInventoryEvent targetEvent) {
        Map<DeviceInventoryState, DeviceInventoryState> eventTransitions = STATE_TRANSITION_MAP.get(targetEvent);
        if (eventTransitions == null) {
            return null;
        }
        return eventTransitions.get(originalState);
    }
    
    /**
     * 获取事件允许的所有原始状态
     * 
     * @param targetEvent 目标事件
     * @return 允许的原始状态集合
     */
    public Map<DeviceInventoryState, DeviceInventoryState> getAllowedTransitions(DeviceInventoryEvent targetEvent) {
        return STATE_TRANSITION_MAP.getOrDefault(targetEvent, new HashMap<>());
    }
    
    /**
     * 获取指定事件的状态转换映射
     * 
     * @param targetEvent 目标事件
     * @return 状态转换映射，如果事件不存在则返回空映射
     */
    public Map<DeviceInventoryState, DeviceInventoryState> getEventTransitions(DeviceInventoryEvent targetEvent) {
        return STATE_TRANSITION_MAP.getOrDefault(targetEvent, new HashMap<>());
    }
    
    /**
     * 批量验证状态转换
     * 
     * @param originalStates 原始状态列表
     * @param targetEvent 目标事件
     * @return 验证结果映射
     */
    public Map<DeviceInventoryState, Boolean> batchValidateTransitions(
            Iterable<DeviceInventoryState> originalStates, DeviceInventoryEvent targetEvent) {
        
        Map<DeviceInventoryState, DeviceInventoryState> eventTransitions = STATE_TRANSITION_MAP.get(targetEvent);
        Map<DeviceInventoryState, Boolean> result = new HashMap<>();
        
        if (eventTransitions == null) {
            // 事件不存在，所有转换都无效
            for (DeviceInventoryState state : originalStates) {
                result.put(state, false);
            }
            return result;
        }
        
        // 高效批量验证
        for (DeviceInventoryState state : originalStates) {
            result.put(state, eventTransitions.containsKey(state));
        }
        
        return result;
    }
    
    /**
     * 获取所有支持的事件类型
     * 
     * @return 支持的事件集合
     */
    public Map<DeviceInventoryEvent, Map<DeviceInventoryState, DeviceInventoryState>> getAllTransitions() {
        return new HashMap<>(STATE_TRANSITION_MAP);
    }
    
    /**
     * 检查事件是否有定义的状态转换规则
     * 
     * @param targetEvent 目标事件
     * @return 是否有转换规则
     */
    public boolean hasTransitionRules(DeviceInventoryEvent targetEvent) {
        Map<DeviceInventoryState, DeviceInventoryState> eventTransitions = STATE_TRANSITION_MAP.get(targetEvent);
        return eventTransitions != null && !eventTransitions.isEmpty();
    }
}